﻿using Server.Attributes;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Server.Message
{

    enum MsgPriority
    {
        Hight,
        Normal,
        Low
    }

    [System]
    class MsgSystem
    {
        readonly ConcurrentQueue<Msg>[] _msgQueues = new ConcurrentQueue<Msg>[3];

        readonly Dictionary<MsgType, List<Action<object>>> _handlers = new();

        void Init()
        {
            _handlers.Clear();

            foreach (MsgType type in Enum.GetValues(typeof(MsgType)))
            {
                if (type == MsgType.None) continue;
                _handlers.Add(type, new());
            }

            for (int i = 0; i < 3; i++)
            {
                _msgQueues[i] = new ConcurrentQueue<Msg>();
            }

            //自绑定reg/unreg
            _handlers[MsgType.MsgReg].Add(Reg);
            _handlers[MsgType.MsgUnreg].Add(Unreg);
        }

        void Start()
        {

        }

        void Update()
        {
            for (int i = 0; i < 3; i++)
            {
                while (!_msgQueues[i].IsEmpty)
                {
                    if (_msgQueues[i].TryDequeue(out Msg msg))
                    {
                        foreach (var action in _handlers[msg.type])
                            action.Invoke(msg.content);

                        Msg.RecycleMsg(msg);
                    }
                    else
                        throw new Exception("======= Update TryDequeue Fail!!!!");
                }
            }
        }

        public void Send(Msg msg)
        {
            Send(msg, MsgPriority.Normal);
        }

        public void Send(Msg msg, MsgPriority priority)
        {
            _msgQueues[(int)priority].Enqueue(msg);
        }


        void Reg(object msg)
        {
            if (msg is not Msg m)
                throw new Exception("======= Reg msg as Msg Fail!!!");

            _handlers[m.type].Add(m.content as Action<object>);
        }

        void Unreg(object msg)
        {
            if (msg is not Msg m)
                throw new Exception("======= Unreg msg as Msg Fail!!!");

            _handlers[m.type].Remove(m.content as Action<object>);
        }

    }



}
